<template>
  <el-container class="area-select">
    <el-main v-loading="loading">
      <el-checkbox
        v-model="checkedAll"
        :indeterminate="isIndeterminate"
        label="全选"
        @change="changeCheckedAll"
      />
      <el-tree
        :data="tree.data"
        node-key="id"
        show-checkbox
        :default-checked-keys="tree.ids"
        @check-change="handleCheckChange"
        ref="treeRef"
      >
        <template #default="{ data }">{{ data.name }}</template>
      </el-tree>
    </el-main>
    <el-footer class="sa-footer--submit">
      <el-button type="primary" @click="confirm">确定</el-button>
    </el-footer>
  </el-container>
</template>

<script>
  export default {
    name: 'AreaSelect',
  };
</script>

<script setup>
  import { computed, nextTick, onMounted, reactive, ref } from 'vue';
  import { api } from '../data.service';

  const emit = defineEmits(['modalCallBack']);
  const props = defineProps(['modal']);

  const checkedAll = ref(false);
  const isIndeterminate = computed(() => (tree.ids.length > 0 && !checkedAll.value ? true : false));
  function changeCheckedAll() {
    if (checkedAll.value) {
      nextTick(() => {
        tree.ids = [];
        treeRef.value?.setCheckedNodes(tree.data, false);
        tree.data.forEach((d) => {
          tree.ids.push(d.id);
          if (!tree.label[d.level]) {
            tree.label[d.level] = {};
          }
          tree.label[d.level][d.id] = d.name;
        });
      });
    } else {
      treeRef.value?.setCheckedKeys([], false);
      tree.ids = [];
      tree.label = {
        province: {},
        city: {},
        district: {},
      };
    }
  }

  const loading = ref(true);
  const treeRef = ref();
  const tree = reactive({
    data: [],
    ids: [],
    label: {},
  });

  async function getData() {
    loading.value = true;
    const { data } = await api.area.select();
    tree.data = data;
    checkedAll.value = props.modal.params.selected.province.split(',').length == tree.data.length;

    loading.value = false;
  }

  function handleCheckChange(data, checked, indeterminate) {
    // 全选
    if (!checkedAll.value) {
      // 选中(把自己放进去)
      if (checked) {
        tree.ids.push(data.id);
        if (!tree.label[data.level]) {
          tree.label[data.level] = {};
        }
        tree.label[data.level][data.id] = data.name;
        if (!indeterminate) {
          deleteIds(data);
        }
      }
    }

    // 未选中(把自己删除)
    if (!checked) {
      if (tree.ids.includes(data.id)) {
        tree.ids.splice(tree.ids.indexOf(data.id), 1);
        for (var key in tree.label[data.level]) {
          if (Number(key) == Number(data.id)) {
            delete tree.label[data.level][key];
          }
        }
      }
      if (indeterminate) {
        addIds(data);
      }
    }

    if (tree.label.province)
      checkedAll.value = Object.keys(tree.label.province).length == tree.data.length;
  }

  function deleteIds(data) {
    let keys = treeRef.value.getCheckedKeys();
    if (data.children && data.children.length > 0) {
      data.children.forEach((d) => {
        if (keys.includes(d.id) && tree.ids.includes(d.id)) {
          tree.ids.splice(tree.ids.indexOf(d.id), 1);
          delete tree.label[d.level][d.id];
        }
        deleteIds(d);
      });
    }
  }

  function addIds(data) {
    let keys = treeRef.value.getCheckedKeys();
    if (data.children && data.children.length > 0) {
      data.children.forEach((d) => {
        if (keys.includes(d.id) && !tree.ids.includes(d.id)) {
          tree.ids.push(d.id);
          if (!tree.label[d.level]) {
            tree.label[d.level] = {};
          }
          tree.label[d.level][d.id] = d.name;
        }
      });
    }
  }

  function confirm() {
    emit('modalCallBack', { event: 'confirm', data: tree.label });
  }

  onMounted(async () => {
    // tree.ids 赋值
    for (var level in props.modal.params.selected) {
      if (props.modal.params.selected[level]) {
        props.modal.params.selected[level].split(',').forEach((id) => {
          tree.ids.push(Number(id));
        });
      }
    }
    await getData();
    nextTick(() => {
      if (treeRef.value) {
        treeRef.value.getCheckedNodes().forEach((data) => {
          if (tree.ids.includes(data.id)) {
            if (!tree.label[data.level]) {
              tree.label[data.level] = {};
            }
            tree.label[data.level][data.id] = data.name;
          }
        });
      }
    });
  });
</script>
